import { createTextNode } from './dom'

class Schedule {
  constructor() {
    this.queue = []
  }
  enqueue(watcher) {
    if (!this.queue.includes(watcher)) {
      this.queue.push(watcher)
    }
    this.run()
  }
  run() {
    this.queue.forEach(watcher => {
      nextTick(watcher.update)
    })
  }
}

let asyncCall = null
let callback = null
if (typeof MutationObserver !== undefined) {
  const observe = new MutationObserver(() => {
    callback?.()
  })
  let count = 1
  const domText = createTextNode()
  domText.textContent = count
  observe.observe(domText, {
    characterData: true
  })
  asyncCall = function (fn) {
    callback = fn
    domText.textContent = count++ % 2
  }
} else if (typeof Promise !== undefined && Promise.then) {
  asyncCall = fn => Promise.resolve().then(fn)
} else {
  asyncCall = fn => setTimeout(fn, 0)
}

function nextTick(fn) {
  return new Promise(resolve => {
    asyncCall(fn)
    resolve()
  })
}

export default new Schedule()
